from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView
from QQLoginTool.QQtool import OAuthQQ
from mall import settings
from .models import OAuthQQUser
# Create your views here.



# 当用户点击a标签的时候，前端会发送一个 ajax请求
# 需要后端 生成一个 qq扫描的url
class QQOauthLoginURLView(APIView):
    """
        GET     /oauth/qq/authorization/
        """
    def get(self,request):
        # ??? 我们看了半天文档不知道这个参数是干什么的
        # 但是我们知道这个参数 必须要传，我们就看到文档中 有一个地方这么写
        # status='test'
        status='/'
        # 1.创建对象
        oauth=OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,
            state=status
        )
        # 2.调用对象的方法获取 url
        auth_url=oauth.get_qq_url()

        # 3.返回响应

        return Response({'auth_url':auth_url})





###################################################################################

from rest_framework import status
from .utils import generic_openid_token
from .serializers import QQOauthUserSerializer


#获取openid函数，跳转到商城页面
class QQOauthUserView(APIView):
    def get(self,request):
        # 1.接受code
        code=request.query_params.get('code')

        if code is None:
            return Response({'msg':'缺少参数'},status=status.HTTP_400_BAD_REQUEST)
        # 2.传递code，获取token
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,

        )

        # 获取外界资源的时候（例如，数据库，redis，网络数据，文件等）

        try:
            access_token=oauth.get_access_token(code)

            # 有了token就可以获取其他信息了，例如 openid

            openid=oauth.get_open_id(access_token)
        #     # print(openid)
        # pass
        #
        except Exception as e:
             print(e)

             return Response({'msg':'获取失败'},status=status.HTTP_400_BAD_REQUEST)




            # 针对于 获取的openid存在2个情况
            # 如果用户之前绑定过，则应该直接登录
            # 如果用户之前没有绑定过，则应该跳转到绑定页面


        try:
            qquser=OAuthQQUser.objects.get(openid=openid)

        except OAuthQQUser.DoesNotExist:

            # 说明不存在
            # 没有绑定过，则应该跳转到绑定页面

            # 1. openid 需要进行加密处理
            # 2. 对openid 这个绑定操作进行一个时间的处理  需要有一定的时效


            openid_token=generic_openid_token(openid)

            return Response({'access_token':openid_token})


        else:

            # else 什么时候执行， 没有异常的时候
            # 说明存在
            # 绑定过，则应该直接登录
            from rest_framework_jwt.settings import api_settings

            # 我们需要获取 2个方法
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

            # 1. jwt_paylaod_handler 我们需要将用户的信息传递给这个函数，函数自己会获取user中的数据
            # 获取了之后，会生成一个二进制
            payload = jwt_payload_handler(qquser.user)
            # 2. 需要对 payload 进行编码，编码之后的才是token
            token = jwt_encode_handler(payload)

            return Response({
                'token': token,
                'user_id': qquser.user.id,
                'username': qquser.user.username
            })




#没有绑定过，则应该跳转到绑定页面，绑定openid页面函数
    def post(self,request):
        # 1.前端将绑定的数据 access_token(openid),mobile,password,sms_code提交给后端
        # 2. 后台接受到数据进行校验
        data=request.data

        serializer=QQOauthUserSerializer(data=data)

        serializer.is_valid(raise_exception=True)
        # 3. 数据入库
        qqusr=serializer.save()

        # 4. 返回响应

        from rest_framework_jwt.settings import api_settings
        # 我们需要获取 2个方法

        jwt_payload_handler=api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        # 1. jwt_paylaod_handler 我们需要将用户的信息传递给这个函数，函数自己会获取user中的数据
        # 获取了之后，会生成一个二进制
        payload=jwt_payload_handler(qqusr.user)
        # 2. 需要对 payload 进行编码，编码之后的才是token
        token=jwt_encode_handler(payload)


        return Response({
            'token':token,
            'user_id':qqusr.user.id,
            'username':qqusr.user.username
        })





